<?php

namespace app\common\model;

use think\Model;
use think\Cache;
use think\Db;

/**
 * 游戏模型
 */
class GameModel extends BaseModel
{
	protected $tableName = 'game';

    /**
     * 修改金币数量
     * @param $user_id:id
     * @param $num:修改金币数
     * @return array|bool 返回原有金币和现有金币
     */
	public function addCoin($user_id,$num)
    {
        //获取原有金币
        $oGold = Db::name('user')->where('id', $user_id)->value('coin');
        //现有金币
        $nGold = $oGold + $num;
        //更新金币数量
        $updateGold = Db::name('user')->where('id', $user_id)->setField('coin', $nGold);
        if ($updateGold === false) {
            return false;
        } else {
            return ['oGold' => $oGold, 'nGold' => $nGold];
        }
    }
    /**
     * 根据日期更新庄家记录
     * @param $game_ename:游戏英文名
     * @param $win_num :false时初始化缓存
     * @return array
     */
    private function updateNumHistory($game_ename,$win_num)
    {
        $num_key = 'game_' . $game_ename . '_win_num';
        $date_key = 'game_' . $game_ename . '_num_date';
        $history_date = Cache::get($date_key);
        $now_date = date('Y-m-d', time());
        if ($win_num !== false) {
            if ($history_date == $now_date) {
                Cache::inc($num_key, $win_num);
            } else {
                Cache::set($date_key, $now_date);
                Cache::set($num_key, $win_num);
            }
        } else {
            Cache::set($date_key, $now_date);
            Cache::set($num_key, 0);
        }
        return [Cache::get($date_key), Cache::get($num_key)];
    }
    /**
     * 更新历史开奖记录
     * @param $cache_key
     * @param $lenth
     * @param $result
     */
    public function updateHistoryWinList($cache_key,$lenth,$result)
    {
        $history_win_list = Cache::get($cache_key);
        if (count($history_win_list) < $lenth) {
            $history_win_list[] = $result;
        } else {
            $history_win_list = array_values($history_win_list);
            unset($history_win_list[0]);
            $history_win_list[] = $result;
            $history_win_list = array_values($history_win_list);
        }
        Cache::set($cache_key, $history_win_list);
    }
    /**
     * 豪车漂移的初始化数据
     * @param $user_id
     * @param $bet_list
     * @return array
     */
    public function getHcpyStatus($user_id,$bet_list)
    {
        $time_status_config = config('hcpy_time_status');
        $time_unit = 0;
        foreach ($time_status_config as $v) {
            $time_unit += $v;
        }
        //当前时间戳
        $time_now = time();
        //当天0点时间戳
        $time_0 = strtotime(date('Y-m-d', $time_now) . '00:00:00');
        //当天过去的秒数
        $second = $time_now - $time_0;
        //过去多少个回合
        $round_num = (int)($second / $time_unit);
        //剩下多少时间
        $second_else = $second % $time_unit;
        $status = 0;
        $second = $second_else;
        foreach ($time_status_config as $k => $v) {
            if ($second - $v >= 0) {
                $second -= $v;
            } else {
                $status = $k;
                $second = $v - $second;
                break;
            }
        }
        $user_gold = model('common/user')->getValue("id=$user_id", 'coin');
        $history_win_list = Cache::get('game_hcpy_win_list');
        //当前日期
        $history_date = Cache::get('game_hcpy_num_date');
        $now_date = date('Y-m-d', time());
        //判断是否需要更新数据
        if ($history_date == $now_date) {
            $banker_gains = Cache::get('game_hcpy_win_num');
        } else {
            $banker_gains = 0;
            Cache::set('game_hcpy_win_num', 0);
        }
        //获取投注情况
        $tznum = 0;
        $tzinfo = [];
        foreach ($bet_list as $k => $v) {
            foreach ($v as $ko => $vo) {
                if ($ko == $user_id) {
                    $tznum += $vo;
                    $tzinfo[$k] = $vo;
                }
            }
        }
        //最后一个开奖的注
        $last_win = end($history_win_list);

        return [
            'code' => 1,
            'operation' => 'JoinRoom',
            'data' => [
                'round_num' => $round_num,
                'status' => $status,
                'second_now' => $second,
                'user_gold' => $user_gold,
                'banker_gains' => $banker_gains,
                'banker_name' => '系统上庄',
                'history_win_list' => $history_win_list ? $history_win_list : [],
                'win_bet' => $last_win,
                'tznum' => $tznum,
                'tzinfo' => $tzinfo
            ]
        ];
    }

    /**
     * 水果机的初始化数据
     * @param $user_id
     * @return array
     */
    public function getSgjStatus($user_id)
    {
        //用户余额
        $gold = model('common/user')->getValue("id=$user_id", 'coin');
        //历史开奖记录
        $history_win_list = Cache::get('game_sgj_win_list');
        return [
            'code' => 1,
            'operation' => 'JoinRoom',
            'data' => [
                'user_gold' => $gold,
                'history_win_list' => $history_win_list ? $history_win_list : [],
            ]
        ];
    }
    /**
     * 飞禽走兽的初始化数据
     * @param $user_id
     * @return array
     */
    public function getFqzsStatus($user_id)
    {
        //用户余额
        $gold = model('common/user')->getValue("id=$user_id", 'coin');
        //历史开奖记录
        $history_win_list = Cache::get('game_fqzs_win_list');
        return [
            'code' => 1,
            'operation' => 'JoinRoom',
            'data' => [
                'user_gold' => $gold,
                'history_win_list' => $history_win_list ? $history_win_list : [],
            ]
        ];
    }
    /**
     * 豪车漂移系统坐庄跑灯结果
     * @param $bet_list
     * @return array
     */
    public function chooseWin_hcpy($bet_list)
    {
        $config = config('hcpy_option');
        //系统预计收益(除去手续费的收益会在这之间浮动)
        $plan_earning = model('common/game')->getValue("id='1'", 'plan_earning');
        $earning = Cache::get('game_hcpy_win_num');
        //判断是否中奖
        $re = ($plan_earning <= $earning) ? true : false;
        //总下注金币数
        $sum_bet_gold = 0;
        //每注下注数
        $bet_win_list = [];
        //当前总盈利数
        $game_hcpy_win_num = Cache::get('game_hcpy_win_num');
        //开始分解计算
        foreach ($bet_list as $k => $v) {
            //当前注下注总数
            $bet_gold = 0;
            foreach ($v as $vo) {
                $sum_bet_gold += $vo;
                $bet_gold += $vo;
            }
            $bet_win_list[$k]['bet_gold'] = $bet_gold;
            //当前注赢的金币
            $bet_win_list[$k]['win_gold'] = $config[$k]['multiple'] * $bet_gold;
        }
        //计算没注结算情况,分解得到盈利和可亏损的注
        $allow_win_arr = [];//赢允许开
        $allow_lose_arr = [];//输允许开
        foreach ($bet_win_list as $k => &$v) {
            $result_gold = $v['win_gold'] - $sum_bet_gold;
            $v['result_gold'] = $result_gold;
            if ($result_gold < 0) {
                $allow_lose_arr[$k] = $v;
            } else {
                $allow_win_arr[$k] = $v;
            }
        }
        unset($v);
        //从集合中按照几率取出结果的函数
        $getOneByOdds = function ($arr) use ($config) {
            //开奖总集合
            $odds_all = 0;
            foreach ($arr as $k => $v) {
                $odds_all += $config[$k]['odds'];
            }
            //随机数
            $num_b = 0;
            $rand = mt_rand(1, $odds_all);
            foreach ($arr as $k => $v) {
                if ($config[$k]['odds'] + $num_b >= $rand) {
                    $re_id = $k;
                    break;
                } else {
                    $num_b += $config[$k]['odds'];
                }
            }
            return $re_id;
        };
        //根据奖池计算结果开奖
        if ($re || count($allow_lose_arr) == 0) {//开赢
            $re_id = $getOneByOdds($allow_win_arr);
        } else {//开输
            $re_id = $getOneByOdds($allow_lose_arr);
        }
        //组装返回数据并写数据库
        $send_data = [];
        $game_hcpy_win_num = 0;
        //系统抽成
        $tax = config('hcpy_sys_tax');
        foreach ($bet_list as $k => $v) {
            foreach ($v as $ko => $vo) {
                if (!isset($send_data[$ko])) {
                    $send_data[$ko] = ['win_num' => 0, 'bet_num' => 0, 'self_result' => 0, 'banker_result' => 0];
                }
                if ($k === $re_id) {
                    $send_data[$ko]['win_num'] += $vo * $config[$k]['multiple'];
                }
                $send_data[$ko]['bet_num'] += $vo;
                //本家结算
                $send_data[$ko]['self_result'] = $send_data[$ko]['win_num'] - $send_data[$ko]['bet_num'];
                //庄家结算
                $send_data[$ko]['banker_result'] = -$send_data[$ko]['self_result'];
                $send_data[$ko]['js_result'] = -$send_data[$ko]['self_result'];
                if ($send_data[$ko]['self_result'] > 0) {
                    $send_data[$ko]['self_result'] = $send_data[$ko]['self_result'] * $tax;
                } else {
                    $send_data[$ko]['banker_result'] = $send_data[$ko]['banker_result'] * $tax;
                }
                $game_hcpy_win_num += $send_data[$ko]['banker_result'];
            }
        }
        //去掉暂时不需要的数据(暂不删除)
        foreach ($bet_list as $k => $v) {
            foreach ($v as $ko => $vo) {
                if (isset($send_data[$ko]['win_num'])) {
                    unset($send_data[$ko]['win_num']);
                }
                if (isset($send_data[$ko]['bet_num'])) {
                    unset($send_data[$ko]['bet_num']);
                }
            }
        }
        //更新数据库
        Db::startTrans();
        try {
            foreach ($send_data as $k => &$v) {
                $addre = $this->addCoin($k, $v['self_result']);
                $v['gold_else'] = ($addre['nGold'] >= 0) ? $addre['nGold'] : 0;
            }
            unset($v);
            // 提交事务

            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
        }
        //更新中奖历史记录
        $this->updateHistoryWinList('game_hcpy_win_list', 10, $re_id);

        $banker_result=0;

        foreach ($send_data as $v){
            $banker_result+=$v['js_result'];
        }
        if($banker_result != 0){
            $numinfo = $this->updateNumHistory('hcpy', $banker_result);
        }

        $send_data['win_bet'] = $re_id;
        return $send_data;
    }

    /**
     * 水果机跑灯结果
     * @param $data
     * @return array
     */
    public function chooseWin_sgj($data)
    {
        $config = config('sgj_option');
        //系统预计收益(除去手续费的收益会在这之间浮动)
        $plan_earning = model('common/game')->getValue("id='2'", 'plan_earning');
        $earning = Cache::get('game_sgj_win_num');
        //判断是否中奖
        $re = ($plan_earning <= $earning) ? true : false;
        //总加权
        $odds_all = 0;
        $bet_detail = [];
        $info = $data['info'];
        //计算总下注金额
        $bet_sum = 0;
        foreach ($info as $v) {
            $bet_sum += $v;
        }
        //扣除下注金额
        $user_gold = $this->addCoin($data['user_id'], -$bet_sum);
        foreach ($config as $k => $v) {
            foreach ($v as $ko => $vo) {
                $odds_all += $vo['odds'];
                if (isset($info[$k])) {
                    if ($info[$k] * $vo['multiple'] - $bet_sum > 0) {
                        $bet_detail['win'][$k . '_' . $ko] = $info[$k] * $vo['multiple'] - $bet_sum;
                    } else {
                        $bet_detail['lose'][$k . '_' . $ko] = $info[$k] * $vo['multiple'] - $bet_sum;
                    }
                    $bet_detail_all[$k . '_' . $ko] = $info[$k] * $vo['multiple'] - $bet_sum;

                } else {
                    $bet_detail['lose'][$k . '_' . $ko] = -$bet_sum;
                    $bet_detail_all[$k . '_' . $ko] = -$bet_sum;
                }
            }
        }
        //随机数
        $num_b = 0;
        $rand = mt_rand(1, $odds_all);
        //随机开出一个判断开1-8、多个、火车
        foreach ($config as $k => $v) {
            foreach ($v as $ko => $vo) {
                if ($vo['odds'] + $num_b >= $rand) {
//                    $result = [$k,$ko];
                    $result = $k;

                    break 2;
                } else {
                    $num_b += $vo['odds'];
                }
            }
        }
        //从$bet_detail中取出一定数量的key
        $randRe = function ($key, $num) use ($bet_detail, $config) {
            unset($bet_detail['lose']['9_0']);
            unset($bet_detail['lose']['10_0']);
            $result_final = [];
            for ($i = 1; $i <= $num; $i++) {
                $odds_all = 0;
                foreach ($bet_detail[$key] as $k => $v) {
                    $k_arr = explode('_', $k);
                    $odds_all += $config[$k_arr[0]][$k_arr[1]]['odds'];
                }
                $num_b = 0;
                $rand = mt_rand(1, $odds_all);
                foreach ($bet_detail[$key] as $k => $v) {
                    $k_arr = explode('_', $k);

                    if ($config[$k_arr[0]][$k_arr[1]]['odds'] + $num_b >= $rand) {
                        $result_final[] = $k;
                        unset($bet_detail[$key][$k]);
                        break;
                    } else {
                        $num_b += $config[$k_arr[0]][$k_arr[1]]['odds'];
                    }
                }
            }
            return $result_final;
        };
        $sgj_list = config('sgj_list');
        switch ($result) {
            case 9://随机开0-3个
                if ($re) {
                    $bet_num = mt_rand(1, 3);
                    $win_num = mt_rand(1, $bet_num);
                    $result_final = $randRe('win', $win_num);
                    if ($bet_num - $win_num > 0) {
                        $result_final =
                            array_merge($result_final, $randRe('lose', $bet_num - $win_num));
                    }
                } else {
                    $bet_num = mt_rand(0, 3);
                    $result_final = $randRe('lose', $bet_num);
                }
                $re_type = 'goodLuck';
                $result_id = [];
                $gold_change = 0;
                foreach ($result_final as $v) {
                    $gold_change += $bet_detail_all[$v] + $bet_sum;
                    $key = array_keys($sgj_list, $v);
                    $result_id[] = $key[mt_rand(0, count($key) - 1)];
                }
                $gold_change -= $bet_sum;
                break;
            case 10://开火车
                $car = [];
                foreach ($bet_detail as $v) {
                    foreach ($v as $k1 => $v1) {
                        foreach ($sgj_list as $k2 => $v2) {
                            if ($v2 == $k1) {
                                $car[$k2] = $v1;
                            }
                        }
                    }
                }
                ksort($car);
                $car_win = [];
                $car_lose = [];
                foreach ($car as $k => $v) {
                    $car_sum = $car[$k]
                        + $car[($k + 1 > 23) ? ($k + 1 - 24) : $k + 1]
                        + $car[($k + 2 > 23) ? ($k + 2 - 24) : $k + 2]
                        + $car[($k + 3 > 23) ? ($k + 3 - 24) : $k + 3]
                        + $car[($k + 4 > 23) ? ($k + 4 - 24) : $k + 4];
                    if ($car_sum > 0) {
                        $car_win[] = [$k,
                            ($k + 1 > 23) ? ($k + 1 - 24) : $k + 1,
                            ($k + 2 > 23) ? ($k + 2 - 24) : $k + 2,
                            ($k + 3 > 23) ? ($k + 3 - 24) : $k + 3,
                            ($k + 4 > 23) ? ($k + 4 - 24) : $k + 4];
                    } else {
                        $car_lose[] = [$k,
                            ($k + 1 > 23) ? ($k + 1 - 24) : $k + 1,
                            ($k + 2 > 23) ? ($k + 2 - 24) : $k + 2,
                            ($k + 3 > 23) ? ($k + 3 - 24) : $k + 3,
                            ($k + 4 > 23) ? ($k + 4 - 24) : $k + 4];
                    }
                }
                if ($re) {
                    $rand = mt_rand(0, count($car_win) - 1);
                    $result_final = array_slice($car_win, $rand, 1);
                } else {
                    $rand = mt_rand(0, count($car_lose) - 1);
                    $result_final = array_slice($car_lose, $rand, 1);
                }
                $result_id = $result_final[0];
                $gold_change = 0;
                foreach ($result_id as $v) {
                    $gold_change += $bet_detail_all[$sgj_list[$v]] + $bet_sum;
                }
                $gold_change -= $bet_sum;
                $re_type = 'car';
                break;
            default://开一个
                $key = $re ? 'win' : 'lose';
                $odds_all = 0;
                foreach ($bet_detail[$key] as $k => $v) {
                    $k_arr = explode('_', $k);
                    $odds_all += $config[$k_arr[0]][$k_arr[1]]['odds'];
                }
                $num_b = 0;
                $rand = mt_rand(1, $odds_all);
                foreach ($bet_detail[$key] as $k => $v) {
                    $k_arr = explode('_', $k);

                    if ($config[$k_arr[0]][$k_arr[1]]['odds'] + $num_b >= $rand) {
                        $result_final = $k;
                        break;
                    } else {
                        $num_b += $config[$k_arr[0]][$k_arr[1]]['odds'];
                    }
                }
                $re_type = 'common';
                $key = array_keys($sgj_list, $result_final);
                $result_id = $key[mt_rand(0, count($key) - 1)];
                $gold_change = $bet_detail_all[$result_final];
                break;
        }
        //更新系统盈利
        $tax = config('sgj_sys_tax');
        if ($gold_change > 0) {
            $gold_change = $gold_change * $tax;
            $sys_gold = -$gold_change;
        } else {
            $sys_gold = -$gold_change * $tax;
        }
        //更新历史赢记录
        switch ($re_type) {
            case 'common':
                $history = $result_id;
                break;
            case 'car':
                $history = 'car';
                break;
            case 'goodLuck':
                if (count($result_final) == 3) {
                    $is_small_three = true;
                    $is_big_three = true;
                    foreach ($result_final as $v) {
                        if (!in_array($v, ['2_0', '3_0', '4_0'])) {
                            $is_small_three = false;
                        }
                        if (!in_array($v, ['5_0', '6_0', '7_0'])) {
                            $is_big_three = false;
                        }
                    }
                    if ($is_small_three == true) {
                        $history = 'smallThree';
                    } elseif ($is_big_three == true) {
                        $history = 'bigThree';
                    } else {
                        $history = 'goodLuck';
                    }
                } else {
                    $history = 'goodLuck';
                }
                break;
            default:
                break;
        }
        $this->updateHistoryWinList('game_sgj_win_list', 8, $history);
        $numinfo = $this->updateNumHistory('sgj', $sys_gold);

        return [
            'code' => 1,
            'operation' => 'WinResult',
            'data' => [
                'type' => $re_type,
                'user_id' => $data['user_id'],
                'game_id' => 2,
                'win_bet' => $result_id,
                'user_gold' => $user_gold['nGold'],
                'self_result' => $gold_change + $bet_sum,
            ]
        ];
    }
    /**
     * 水果机猜大小结果
     * @param $data
     * @return array
     */
    public function chooseWin_sgj_1($data)
    {
        //系统预计收益(除去手续费的收益会在这之间浮动)
        $plan_earning = model('common/game')->getValue("id='2'", 'plan_earning');
        $earning = Cache::get('game_sgj_win_num');
        //判断是否中奖
        $re = ($plan_earning <= $earning) ? true : false;
        //判断开哪个奖
        $winId = (($data['info']['id'] == 1) == $re) ? 1 : 2;
        $self_result = $re ? $data['info']['num'] : -$data['info']['num'];
        $gold = model('common/game')->addCoin($data['user_id'], $data['info']['num_get']);
        //新增下注数据
        $data_log = [
            'user_id' => $data['user_id'],
            'game_id' => 2,
            'site_id' => 1,//TODO::siteid
            'bet_gold' => $data['info']['num'],
            'win_result' => $re ? 1 : 0,
            'win_gold' => $re ? $data['info']['num'] : -$data['info']['num'],
            'updated_time' => date('Y-m-d H:i:s', time())
        ];
        db('game_bet')->insert($data_log);
        $this->updateNumHistory('sgj', -$self_result);
        return [
            'code' => 1,
            'operation' => 'getWinResult',
            'data' => [
                'type' => 1,
                'game_id' => 2,
                'user_id' => $data['user_id'],
                'win_bet' => $winId,
                'self_result' => $data['info']['num'] + $self_result,//结算
                'user_gold' => $gold['nGold'],//现有金币
            ]
        ];
    }
    /**
     * 飞禽走兽跑灯结果
     * */
    public function chooseWin_fqzs($re,$data,$zArr){
        $info = $data['info'];
        $type_info = json_decode($data['type_info'],true);
        $uname = $data['uname'];
        //下注总金币
        $zNum = 0;
        $info_n = [];
        foreach ($info as $v) {
            $zNum += $v['num'];
            $info_n[$v['id']] = $v;
        };
        foreach ($type_info as $v){
            $zNum += $v;
        }
        //id作为键
        $info = $info_n;
        //取出会赢钱的注
        $win_list = [];
        //亏钱的注
        $lose_list = $zArr;
        unset($lose_list[11]);
        foreach ($info as $v) {
            $sum_get = $zArr[$v['id']]['multiple'] * $v['num'];
            if($zArr[$v['id']]['type'] != 0){
                $sum_get += $type_info[$zArr[$v['id']]['type']]*2;
            }
            if ($sum_get > $zNum) {
                $win_list[$v['id']] = $v;
                unset($lose_list[$v['id']]);
            }
        }
        //通赔加入
        $win_list[11]=$zArr[11];

        //根据奖池结论判断中奖的注
        if ($re) {
            $key_arr = array_keys($win_list);
            $sum = 0;
            foreach ($key_arr as $v) {
                $sum += $zArr[$v]['odds'] * 1000;
            }
            $num_b = 0;
            $per = mt_rand(1, $sum);
            foreach ($key_arr as $v) {
                if ($zArr[$v]['odds'] * 1000 + $num_b >= $per) {
                    $re_id = $v;
                    break;
                } else {
                    $num_b += $zArr[$v]['odds'] * 1000;
                }
            }
        } else {
            //控制几率
            $sum = 0;
            foreach ($lose_list as $v) {
                $sum += $v['odds'] * 1000;
            }
            $num_b = 0;
            $per = mt_rand(1, $sum);
            foreach ($lose_list as $k=>$v) {
                if ($v['odds'] * 1000 + $num_b >= $per) {
                    $re_id = $k;
                    break;
                } else {
                    $num_b += $v['odds'] * 1000;
                }
            }
        }
        $getGold = 0;
        if($re_id == 11){
            foreach($info as $v){
                $getGold += $zArr[$v['id']]['multiple'] * $info[$v['id']]['num'];
            }
            foreach($type_info as $vo){
                $getGold += $vo*2;
            }
        }else if (isset($info[$re_id])) {
            $getGold += $zArr[$re_id]['multiple'] * $info[$re_id]['num'];
        }
        if(isset($type_info[$zArr[$re_id]['type']])){
            $getGold+=$type_info[$zArr[$re_id]['type']]*2;
        }
        $gold=$this->addCoin($uname,$getGold - $zNum);
        return [
            'code'=>1,
            'result' => $re ? 1 : 0,
            'winId' => $re_id,
            'winType' => $zArr[$re_id]['type'],
            'uInfo' => [
                'jGold' => $getGold,//下注中奖金币
                'zGold' => $zNum,//下注金币
                'yGold' => $getGold - $zNum,//赢取金币
                'oGold' => $gold['oGold'],//原有金币
                'nGold' => $gold['nGold'],//现有金币
            ]
        ];

    }

    public function chooseWin_5($data){
        $cards = str_split('1111222233334444555566667777888899990000JJJJQQQQKKKK');
        // 洗牌
        shuffle($cards);
        // 假设游戏人数为4人 默认发排顺序为 A > B > C > D
        $a = array($cards[0], $cards[4], $cards[8], $cards[12], $cards[16]);
        $b = array($cards[1], $cards[5], $cards[9], $cards[13], $cards[17]);
        $c = array($cards[2], $cards[6], $cards[10], $cards[14], $cards[18]);
        $d = array($cards[3], $cards[7], $cards[11], $cards[15], $cards[19]);
        $lottery=new \app\common\library\NiuNiuGame();
        $re=$lottery->JudgeCowCow($a);
        return $re;
    }
}
